home *** CD-ROM | disk | FTP | other *** search
- /*
- File: ZoomRecter.c
-
- Contains: This snippet shows how to do "Finder" style zooming between two rectangles.
- The boolean flag "kZoomLarger" controls the proportional direction of the
- zooming.
-
- To get the two rectangles, you drag them out rubberbanded, and the zoom
- occurs between them. To quit, click the close box.
-
- If you want to do zooms between windows, open up a port with the dimensions
- of the desktop (from GetGrayRgn()).
-
- DON'T use this as a sample of how to do rubberband drawing!!! It's sort of
- hacked together bypassing the event mechanism and just using Button().
-
- Written by: SF
-
- Copyright: Copyright © 1992-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 08/2000 JM Carbonized, non-Carbon code is commented out
- for demonstration purposes. Changed basic code
- significantly so it would simply work better.....
- 7/14/1999 KG Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
- #include "CarbonPrefix.h"
- #include <Dialogs.h>
- #include <Fonts.h>
-
- #define kNumSteps 14
- #define kRectsVisible 4
- #define kZoomRatio .7
- #define kDelayTicks 1
-
- #define kZoomLarger true // change this to zoom "inward"
-
-
- void InitStuff(void);
- void ZoomRect(Boolean zoomOut,Rect *smallRect, Rect *bigRect);
- void CalcRect(Rect *theRect,Rect *smallRect,Rect *bigRect,double stepValue);
- //Boolean GetRects(Rect *zoomFrom,Rect *zoomTo);
- void FixRect(Rect *theRect,Rect *rightRect);
- void doEventLoop();
- void GetRect(Rect *zoomFrom, Rect *zoomTo);
-
- Boolean gDone = false;
- WindowPtr gWindow;
-
- void main(void)
- {
-
- Rect bounds = {44,12,330,500}/*,zoomFrom,zoomTo*/;
- //Rect tempRect1; //used for carbonization
-
- InitStuff();
- gWindow = NewWindow(nil,&bounds,"\pDrag Two Rects to Zoom",true,documentProc,(WindowPtr)-1L,true,0);
- //SetPort(window);
- SetPortWindowPort(gWindow);
-
- /*do {
- if (GetRects(&zoomFrom,&zoomTo))
- ZoomRect(kZoomLarger,&zoomFrom,&zoomTo);
- //EraseRect(&window->portRect);
- EraseRect(GetPortBounds(GetWindowPort(window), &tempRect1));
- }
- while (!gDone);*/
-
- doEventLoop();
-
- FlushEvents(everyEvent,0);
- }
-
-
- void InitStuff(void)
- {
- //InitGraf(&qd.thePort);
- //InitFonts();
- //InitWindows();
- //InitMenus();
- //TEInit();
- //InitDialogs(nil);
- InitCursor();
- FlushEvents(everyEvent,0);
- }
-
-
- void ZoomRect(Boolean zoomLarger,Rect *smallRect, Rect *bigRect)
- {
- double firstStep,stepValue,trailer,zoomRatio;
- short i,step;
- Rect curRect;
- unsigned long ticks;
- Pattern grayPattern; //used in carbonization
- RgnHandle rgnHandle = NewRgn();
- GrafPtr oldPort;
- Rect tempRect1;
-
- GetPort(&oldPort);
- SetPort(GetWindowPort(gWindow));
-
- //PenPat(&qd.gray);
- PenPat(GetQDGlobalsGray(&grayPattern));
- PenMode(patXor);
-
-
- firstStep=kZoomRatio;
- for (i=0; i<kNumSteps; i++) {
- firstStep *= kZoomRatio;
- }
-
- if (!zoomLarger) {
- zoomRatio = 1.0/kZoomRatio;
- firstStep = 1.0-firstStep;
- }
- else
- zoomRatio = kZoomRatio;
-
- trailer = firstStep;
- stepValue = firstStep;
- for (step=0; step<(kNumSteps+kRectsVisible); step++) {
-
- // draw new frame
-
- if (step<kNumSteps) {
- stepValue /= zoomRatio;
- CalcRect(&curRect,smallRect,bigRect,stepValue);
- FrameRect(&curRect);
- }
-
- // erase old frame
-
- if (step>=kRectsVisible) {
- trailer /= zoomRatio;
- CalcRect(&curRect,smallRect,bigRect,trailer);
- FrameRect(&curRect);
- }
- QDFlushPortBuffer(GetWindowPort(gWindow), GetPortVisibleRegion(GetWindowPort(gWindow), rgnHandle));
- Delay(kDelayTicks,&ticks);
-
- }
-
- PenNormal();
- DisposeRgn(rgnHandle);
- smallRect->top = bigRect->top = -1;
- EraseRect(GetPortBounds(GetWindowPort(gWindow), &tempRect1));
-
- SetPort(oldPort);
- }
-
-
- void CalcRect(Rect *theRect,Rect *smallRect,Rect *bigRect,double stepValue)
- {
- theRect->left = smallRect->left + (short)((double)(bigRect->left-smallRect->left)*stepValue);
- theRect->top = smallRect->top + (short)((double)(bigRect->top-smallRect->top)*stepValue);
- theRect->right = smallRect->right + (short)((double)(bigRect->right-smallRect->right)*stepValue);
- theRect->bottom = smallRect->bottom + (short)((double)(bigRect->bottom-smallRect->bottom)*stepValue);
- }
-
- // Old version, would require that you drag 2 rects before letting the event loop continue
- /*Boolean GetRects(Rect *zoomFrom,Rect *zoomTo)
- {
- short numRects = 0;
- //EventRecord ev;
- Rect theRect,drawRect;
- Point firstPt,curPt,oldPt,globalPt;
- //KeyMap theKeys;
- WindowPtr window;
- Boolean result = true;
- RgnHandle rgnHandle = NewRgn();
-
- PenMode(patXor);
-
- do {
- while (!Button()) {
-
- GetMouse(&globalPt);
- LocalToGlobal(&globalPt);
- if ((FindWindow(globalPt,&window)==inGoAway) && window==FrontWindow()) {
- gDone = true;
- result = false;
- }
-
- GetMouse(&firstPt);
- oldPt = firstPt;
- SetRect(&theRect,firstPt.h,firstPt.v,firstPt.h,firstPt.v);
- }
-
- if (gDone)
- break;
-
- while (Button()) {
- GetMouse(&curPt);
- if (!EqualPt(curPt,oldPt)) {
- FixRect(&theRect,&drawRect);
- FrameRect(&drawRect);
- oldPt = curPt;
- theRect.right = curPt.h;
- theRect.bottom = curPt.v;
- FixRect(&theRect,&drawRect);
- FrameRect(&drawRect);
- }
- }
-
- FixRect(&theRect,&drawRect);
- if (numRects==0)
- *zoomFrom = drawRect;
- else
- *zoomTo = drawRect;
-
- numRects++;
-
- QDFlushPortBuffer(GetWindowPort(window), GetPortVisibleRegion(GetWindowPort(window), rgnHandle));
-
- } while (numRects<2);
-
- PenNormal();
- DisposeRgn(rgnHandle);
-
- return result;
- }*/
-
- // New Version of GetRect(s), modified from original to only handle one dragged rect at a time.
-
- void GetRect(Rect *zoomFrom, Rect *zoomTo)
- {
- static short numRects = 0;
- Rect theRect,drawRect;
- Point firstPt,curPt,oldPt;
- RgnHandle rgnHandle = NewRgn();
- GrafPtr oldPort;
-
- GetPort(&oldPort);
- SetPort(GetWindowPort(gWindow));
-
- PenMode(patXor);
-
- GetMouse(&firstPt);
- oldPt = firstPt;
- SetRect(&theRect,firstPt.h,firstPt.v,firstPt.h,firstPt.v);
-
- while (Button()) {
- GetMouse(&curPt);
- if (!EqualPt(curPt,oldPt)) {
- FixRect(&theRect,&drawRect);
- FrameRect(&drawRect);
- oldPt = curPt;
- theRect.right = curPt.h;
- theRect.bottom = curPt.v;
- FixRect(&theRect,&drawRect);
- FrameRect(&drawRect);
- QDFlushPortBuffer(GetWindowPort(gWindow), GetPortVisibleRegion(GetWindowPort(gWindow), rgnHandle));
- }
- }
-
- FixRect(&theRect,&drawRect);
- if (numRects==0)
- *zoomFrom = drawRect;
- else
- *zoomTo = drawRect;
-
- numRects++;
-
- QDFlushPortBuffer(GetWindowPort(gWindow), GetPortVisibleRegion(GetWindowPort(gWindow), rgnHandle));
-
- if (numRects >= 2) {
- ZoomRect(kZoomLarger, zoomFrom, zoomTo);
- numRects = 0;
- }
-
- PenNormal();
- DisposeRgn(rgnHandle);
- SetPort(oldPort);
-
- }
-
-
- void FixRect(Rect *theRect,Rect *rightRect)
- {
- if (theRect->right > theRect->left) {
- rightRect->right = theRect->right;
- rightRect->left = theRect->left;
- }
- else {
- rightRect->right = theRect->left;
- rightRect->left = theRect->right;
- }
-
- if (theRect->bottom > theRect->top) {
- rightRect->bottom = theRect->bottom;
- rightRect->top = theRect->top;
- }
- else {
- rightRect->bottom = theRect->top;
- rightRect->top = theRect->bottom;
- }
-
- }
-
- void doEventLoop()
- {
- EventRecord anEvent;
- WindowPtr evtWind;
- short clickArea;
- Rect screenRect;
- Point thePoint;
- Rect zoomFrom, zoomTo;
-
- zoomFrom.top = zoomTo.top = -1;
-
- while (!gDone)
- {
- if (WaitNextEvent( everyEvent, &anEvent, 0, nil ))
- {
- if (anEvent.what == mouseDown)
- {
- clickArea = FindWindow( anEvent.where, &evtWind );
-
- if (clickArea == inDrag)
- {
- GetRegionBounds( GetGrayRgn(), &screenRect );
- DragWindow( evtWind, anEvent.where, &screenRect );
- }
- else if (clickArea == inContent)
- {
- if (evtWind != FrontWindow())
- SelectWindow( evtWind );
- else
- {
- thePoint = anEvent.where;
- GlobalToLocal( &thePoint );
- //Handle click in window content here
- GetRect(&zoomFrom, &zoomTo);
- }
- }
- else if (clickArea == inGoAway)
- if (TrackGoAway( evtWind, anEvent.where ))
- gDone = true;
- }
- else if (anEvent.what == updateEvt)
- {
- evtWind = (WindowPtr)anEvent.message;
- SetPortWindowPort( evtWind );
-
- BeginUpdate( evtWind );
- //Call Draw Function here....
- if (zoomFrom.top != -1)
- FrameRect(&zoomFrom);
- if (zoomTo.top != -1)
- FrameRect(&zoomTo);
- EndUpdate (evtWind);
- }
- }
- }
- }